package com.music.playlist.controllers;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import com.music.client.playlist.client.PlaylistClient;
import com.music.playlist.logging.PlaylistLogger;
import com.music.service.members.beans.Member;
import com.music.service.playlists.beans.Playlist;
import com.music.service.playlists.exceptions.InvalidUrlException;

import static com.music.playlist.constants.PlaylistConstants.*;

public class MyPlaylistController extends MultiActionController {

	private String mViewPlaylistView;
	private String mEditPlaylistView;
	private String mDeletePlaylistView;
	private String mAddPlaylistView;
	private String mAddSongView;
	private String mExceptionView;

	private PlaylistClient mPlaylistClient;
	private static final Logger log = PlaylistLogger.getLogger();
	
	/**
	 * Method to view songs of a playlist
	 * @param pRequest
	 * @param pResponse
	 * @return ModelAndView
	 * @throws ServletException
	 * @throws IOException
	 */
	public ModelAndView viewPlaylist(HttpServletRequest pRequest,
			HttpServletResponse pResponse) throws ServletException, IOException {
		ModelAndView modelAndView = new ModelAndView();
		Long pMemberId = null;
		Long pPlaylistId = null;
		try {
			pMemberId = getMemberId(pRequest);
			pPlaylistId = getPlaylistId(pRequest);
		} catch (NumberFormatException nfe) {
			modelAndView.setViewName(getExceptionView());
			modelAndView.addObject(EXCEPTION_MESSAGE,
					"Invalid Member Id or Playlist Id");
			return modelAndView;
		}

		Playlist playlist = getPlaylistClient().getPlaylistSongsForMember(
				pMemberId, pPlaylistId);
		List<Playlist> recentPlaylist = getPlaylistClient().getRecentPlaylists(
				pMemberId);

		modelAndView.addObject(PLAYLIST, playlist);
		modelAndView.addObject(RECENT_PLAYLISTS, recentPlaylist);
		modelAndView.setViewName(getViewPlaylistView());

		return modelAndView;
	}
	public ModelAndView addSongToPlaylist(HttpServletRequest pRequest,
			HttpServletResponse pResponse) throws ServletException, IOException {
		ModelAndView modelAndView = new ModelAndView(getAddSongView());
		Long pMemberId = null;
		Long pPlaylistId = null;
		String songName = null,songUrl = null;
		try {
			pMemberId = getMemberId(pRequest);
			pPlaylistId = getPlaylistId(pRequest);
			songName = getSongName(pRequest);
			songUrl = getSongUrl(pRequest);
		} catch (NumberFormatException nfe) {
			modelAndView.setViewName(getExceptionView());
			modelAndView.addObject(EXCEPTION_MESSAGE,
					"Invalid Member Id or Playlist Id");
			return modelAndView;
		}
		Playlist playlist = null;
		try {
			 playlist = getPlaylistClient().addSongToPlaylist(pMemberId, pPlaylistId, songName, songUrl);
		} catch (IllegalAccessException e) {
			modelAndView.setViewName(getExceptionView());
			modelAndView.addObject(EXCEPTION_MESSAGE,
					"You don't have permission to add song in this playlist");
			e.printStackTrace();
			
			return modelAndView;
		} catch (InvalidUrlException e) {
			modelAndView.setViewName(getExceptionView());
			modelAndView.addObject(EXCEPTION_MESSAGE,
					"Url is not valid");
			e.printStackTrace();
			return modelAndView;
		} catch (Exception e) {
			modelAndView.setViewName(getExceptionView());
			modelAndView.addObject(EXCEPTION_MESSAGE,
					"Internal server error");
			e.printStackTrace();
			return modelAndView;
		}
		List<Playlist> recentPlaylist = getPlaylistClient().getRecentPlaylists(pMemberId);
		modelAndView.addObject(PLAYLIST,playlist);
		modelAndView.addObject(RECENT_PLAYLISTS,recentPlaylist);
		return modelAndView;
	}
	private String getSongUrl(HttpServletRequest pRequest) {
		return pRequest.getParameter(PARAM_SONG_URL);
	}
	private String getSongName(HttpServletRequest pRequest) {
		return pRequest.getParameter(PARAM_SONG_NAME);
	}
	/**
	 * Method to edit playlist properties such as playlist name,shuffle,repeat etc.
	 * @param pRequest
	 * @param pResponse
	 * @return ModelAndView
	 * @throws ServletException
	 * @throws IOException
	 */
	public ModelAndView editPlaylist(HttpServletRequest pRequest,
			HttpServletResponse pResponse) throws ServletException, IOException {
		ModelAndView modelAndView = new ModelAndView(getEditPlaylistView());
		Long pMemberId = null;
		Long pPlaylistId = null;
		try {
			pMemberId = getMemberId(pRequest);
			pPlaylistId = getPlaylistId(pRequest);
		} catch (NumberFormatException nfe) {
			modelAndView.setViewName(getExceptionView());
			modelAndView.addObject(EXCEPTION_MESSAGE,
					"Invalid Member Id or Playlist Id");
			return modelAndView;
		}
		//Playlist playlist = getPlaylistClient().editPlaylist(pPlaylist);
		return modelAndView;
	}

	/**
	 * Method to delete playlist 
	 * @param pRequest
	 * @param pResponse
	 * @return ModelAndView
	 * @throws ServletException
	 * @throws IOException
	 */
	public ModelAndView deletePlaylist(HttpServletRequest pRequest,
			HttpServletResponse pResponse) throws ServletException, IOException {
		ModelAndView modelAndView = new ModelAndView(getDeletePlaylistView());
		Long pMemberId = null;
		Long pPlaylistId = null;
		try {
			pMemberId = getMemberId(pRequest);
			pPlaylistId = getPlaylistId(pRequest);
		} catch (NumberFormatException nfe) {
			modelAndView.setViewName(getExceptionView());
			modelAndView.addObject(EXCEPTION_MESSAGE,	"Invalid Member Id or Playlist Id");
			return modelAndView;
		}
		Playlist playlist = new Playlist();
		playlist.setMemberId(pMemberId);
		playlist.setPlaylistId(pPlaylistId);
		
		getPlaylistClient().deletePlaylist(playlist);
		
		return modelAndView;
	}

	/**
	 * Method to add playlist 
	 * @param pRequest
	 * @param pResponse
	 * @return ModelAndView
	 * @throws ServletException
	 * @throws IOException
	 */
	public ModelAndView addPlaylist(HttpServletRequest pRequest,
			HttpServletResponse pResponse) throws ServletException, IOException {
		ModelAndView modelAndView = new ModelAndView(getAddPlaylistView());
		Long pMemberId = null;
		String pPlaylistName = null;
		try {
			pMemberId = getMemberId(pRequest);
			pPlaylistName = pRequest.getParameter(PARAM_PLAYLIST_NAME);
		} catch (NumberFormatException nfe) {
			modelAndView.setViewName(getExceptionView());
			modelAndView.addObject(EXCEPTION_MESSAGE,	"Invalid Member Id ");
			return modelAndView;
		}
		
		log.debug("Memberid="+pMemberId+":adding new playlist="+pPlaylistName);
		System.out.println("Memberid="+pMemberId+":adding new playlist="+pPlaylistName);
		Playlist playlist = new Playlist();
		playlist.setMemberId(pMemberId);
		playlist.setPlaylistName(pPlaylistName);
		
		Playlist newPlaylist = getPlaylistClient().addPlaylist(playlist);
		
		List<Playlist> myPlaylist = getPlaylistClient().viewPlaylists(pMemberId);
		List<Playlist> recentPlaylist = getPlaylistClient().getRecentPlaylists(pMemberId);
		if(myPlaylist != null){
			log.debug("Number of playlists="+myPlaylist.size());
		}
		modelAndView.addObject(MY_PLAYLISTS,myPlaylist);
		modelAndView.addObject(RECENT_PLAYLISTS,recentPlaylist);
		return modelAndView;
	}

	/**
	 * 
	 * @param pRequest
	 * @return
	 */
	private Long getMemberId(HttpServletRequest pRequest){
		Member member = (Member) pRequest.getAttribute("member");
		return member.getMemberId();
	}
	
	/**
	 * 
	 * @param pRequest
	 * @return
	 */
	private Long getPlaylistId(HttpServletRequest pRequest){
		return Long.valueOf(pRequest.getParameter(PARAM_PLAYLIST_ID));
	}
	
	
	/**
	 * @return the viewPlaylistView
	 */
	public String getViewPlaylistView() {
		return mViewPlaylistView;
	}

	/**
	 * @param pViewPlaylistView
	 *            the viewPlaylistView to set
	 */
	@Required
	public void setViewPlaylistView(String pViewPlaylistView) {
		mViewPlaylistView = pViewPlaylistView;
	}

	/**
	 * @return the editPlaylistView
	 */
	public String getEditPlaylistView() {
		return mEditPlaylistView;
	}

	/**
	 * @param pEditPlaylistView
	 *            the editPlaylistView to set
	 */
	@Required
	public void setEditPlaylistView(String pEditPlaylistView) {
		mEditPlaylistView = pEditPlaylistView;
	}

	/**
	 * @return the deletePlaylistView
	 */
	public String getDeletePlaylistView() {
		return mDeletePlaylistView;
	}

	/**
	 * @param pDeletePlaylistView
	 *            the deletePlaylistView to set
	 */
	@Required
	public void setDeletePlaylistView(String pDeletePlaylistView) {
		mDeletePlaylistView = pDeletePlaylistView;
	}

	/**
	 * @return the exceptionView
	 */
	public String getExceptionView() {
		return mExceptionView;
	}

	/**
	 * @param pExceptionView
	 *            the exceptionView to set
	 */
	@Required
	public void setExceptionView(String pExceptionView) {
		mExceptionView = pExceptionView;
	}

	/**
	 * @return the addPlaylistView
	 */
	public String getAddPlaylistView() {
		return mAddPlaylistView;
	}

	/**
	 * @param pAddPlaylistView the addPlaylistView to set
	 */
	@Required
	public void setAddPlaylistView(String pAddPlaylistView) {
		mAddPlaylistView = pAddPlaylistView;
	}

	/**
	 * @return the playlistClient
	 */
	public PlaylistClient getPlaylistClient() {
		return mPlaylistClient;
	}

	/**
	 * @param pPlaylistClient
	 *            the playlistClient to set
	 */
	@Required
	public void setPlaylistClient(PlaylistClient pPlaylistClient) {
		mPlaylistClient = pPlaylistClient;
	}

	/**
	 * @return the addSongView
	 */
	public String getAddSongView() {
		return mAddSongView;
	}

	/**
	 * @param pAddSongView the addSongView to set
	 */
	public void setAddSongView(String pAddSongView) {
		mAddSongView = pAddSongView;
	}

}
